package com.caiyouxi.pay.service;

import com.alibaba.fastjson.JSONObject;
import com.caiyouxi.common.Constant;
import com.caiyouxi.common.bean.ResData;
import com.caiyouxi.common.exception.BusinessException;
import com.caiyouxi.common.exception.ErrorCode;
import com.caiyouxi.common.service.BaseService;
import com.caiyouxi.common.util.Log;
import com.caiyouxi.finance.model.FinanceAccount;
import com.caiyouxi.finance.model.FinanceCurrency;
import com.caiyouxi.finance.model.FinanceTradeDetail;
import com.caiyouxi.finance.model.FinanceTradeReceivable;
import com.caiyouxi.finance.service.*;
import com.caiyouxi.goods.model.GoodsDiscount;
import com.caiyouxi.goods.model.GoodsInfo;
import com.caiyouxi.goods.service.GoodsDiscountsService;
import com.caiyouxi.goods.service.GoodsInfoService;
import com.caiyouxi.order.model.OrderBean;
import com.caiyouxi.order.service.OrderService;
import com.caiyouxi.pay.mapper.PayMapper;
import com.caiyouxi.pay.model.PayTypeBean;
import com.caiyouxi.pay.model.PaymentBean;
import com.caiyouxi.pay.model.PaymentConfigBean;
import com.caiyouxi.pay.model.PaymentLogBean;
import com.caiyouxi.pay.payment.alipay.AlipayPayService;
import com.caiyouxi.pay.payment.weixin.WxPayService;
import com.caiyouxi.system.service.SysLogBeanService;
import org.apache.log4j.Logger;
import org.nutz.json.Json;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.List;

/**
 * 支付service类
 * weichangyong
 *
 * @create 2017-08-31 15:16
 **/
@Service
public class PayServiceImpl extends BaseService {

    @Autowired
    private PayMapper payMapper;
    @Autowired
    private FinanceCurrencyService financeCurrencyService;
    @Autowired
    private FinanceAccountService financeAccountService;

    @Autowired
    private PayServiceImpl payService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private FinanceTradeDetailService financeTradeDetailService;
    @Autowired
    private FinanceTradeReceivableService financeTradeReceivableService;
    @Autowired
    private AccountPayService accountPayService;
    @Autowired
    private GoodsDiscountPayService goodsDiscountPayService;
    @Autowired
    private GoodsInfoService goodsInfoService;
    @Autowired
    private GoodsDiscountsService goodsDiscountsService;
    @Autowired
    private CouponsPayService couponsPayService;
    @Autowired
    private SysLogBeanService sysLogBeanService;
    @Autowired
    private CouponsService couponsService;


    private Logger logger = Logger.getLogger(PayServiceImpl.class);

    /**
     * 根据产品获取支付方式
     * 查询内置的第三方支付，在根据商品的货币类型查询
     * @param bean
     * @return
     */
    public List<PaymentConfigBean> get_product_payment(PaymentConfigBean bean)
    {
        //查询订单ID
//        OrderBean order = orderService.get_order_by_id(bean.getOrder_id());
//        if(null==order)
//        {
//            Log.e(ErrorCode.ORDER_NOT_FOUND.getMsg());
//            return failed(ErrorCode.ORDER_NOT_FOUND);
//        }
//        //订单 状态必须是待支付
//        if(!Constant.ORDER_STATUS_UNPAIED.equals(order.getStatus()))
//        {
//            Log.e(ErrorCode.ORDER_STATUS_ERROR.getMsg());
//            return failed(ErrorCode.ORDER_STATUS_ERROR);
//        }


        //search redis
        String redis_key = "PRODUCT_PAYMENT_"+"_"+bean.getApp_id();
        Log.d("search redis,key:"+redis_key);
        List<PaymentConfigBean> list = (List<PaymentConfigBean>) redisService.get(redis_key);

        //根据APP_ID查询商品信息
        GoodsInfo goods = goodsInfoService.select_goods_info_by_app_id(bean.getApp_id());

        //查询商品的支付方式
        //根据goods>goods_category>app>_product_line
        String target_type = "GOODS";
        String target_id = String.valueOf(goods.getId());

        PaymentConfigBean search_bean = new PaymentConfigBean();
        search_bean.setTarget_type(target_type);
        search_bean.setTarget_id(target_id);
        list = payMapper.get_product_payment(search_bean);

        //根据商品品类查询支付方式
        if(null==list || list.size()==0)
        {
            target_type ="GOODS_CATEGORY";
            target_id = String.valueOf(goods.getCategory_id());
        }
        search_bean.setTarget_type(target_type);
        search_bean.setTarget_id(target_id);
        list = payMapper.get_product_payment(search_bean);

        //根据APP查询支付方式
        if(null==list || list.size()==0)
        {
            target_type ="APP";
            target_id = String.valueOf(bean.getApp_id());
        }
        search_bean.setTarget_type(target_type);
        search_bean.setTarget_id(target_id);
        list = payMapper.get_product_payment(search_bean);

        //根据Product_line查询支付方式
        if(null==list || list.size()==0)
        {
            target_type ="PRODUCT_LINE";
            target_id = String.valueOf(bean.getProduct_line_code());
        }
        search_bean.setTarget_type(target_type);
        search_bean.setTarget_id(target_id);
        list = payMapper.get_product_payment(search_bean);


        redisService.set(redis_key,list);

        //查询账户支付及账户balance

        //根据货币类型，查询出货币类型
        FinanceCurrency fcbean = financeCurrencyService.get_finance_currency_by_code(goods.getCurrency_code());
        if("RMB".equals(fcbean.getBuying_currency_type()))
        {
            //当CODE,TYPE都是RMB是代表只允许第三方支付
        }
        else
        {
            //查询此账户的balance
            FinanceAccount account = financeAccountService.select_finance_account_by_uiaccaac(goods.getCurrency_code(),goods.getAccount_code(),bean.getUser_id());
            if(account == null){
                //没有，新增该账户信息
                boolean specify = false;
                if("PRIMARY".equals(goods.getAccount_code())){
                    specify = true;
                }
                account = financeAccountService.add_finance_account(bean.getUser_id(),goods.getAccount_code(),goods.getCurrency_code(),0,specify,"初始化用户");
            }

            PaymentConfigBean pcb = get_payment_config(account);
            if(null!=pcb)
            {
                list.add(pcb);
            }
        }

        //放入缓存
        redisService.set(redis_key,list);
        return list;
    }

    /**
     * 根据商品查询商品支持的账户支付方式
     * @param
     * @return
     */
    public PaymentConfigBean get_payment_config(FinanceAccount bean )
    {

        //判断账户状态
        int balance = 0;
        if(null!=bean)
        {
            balance = bean.getBalance()==null?0:bean.getBalance();
        }
        else {
            return null;
        }
        //查询货币类型
        FinanceCurrency fc = financeCurrencyService.get_finance_currency_by_code(bean.getCurrency_code());
        PaymentConfigBean cb = new PaymentConfigBean();
        cb.setBalance(String.valueOf(balance / 100.00));
        cb.setProvider("ACCOUNT");
        cb.setShow_name(fc.getName());
        cb.setUnit(fc.getUnit());
        cb.setAd("");
        cb.setStatus(bean.getStatus());
        cb.setPay_id(9999);
        return cb;
    }



    public PaymentConfigBean get_payment_detail(int product_pay_id)
    {
        return payMapper.get_product_payment_by_pay_id(product_pay_id);
    }


    /**
     * 第三方支付
     * 根据支付方式去第三方统一下单
     * @param bean
     * @return
     */
    public ResData get_pay_resp(OrderBean bean) throws Exception {
        JSONObject obj = new JSONObject();

        OrderBean order = orderService.get_order_by_id(bean.getId());
        if(null==order)
        {
            Log.e("订单不存在..");
            return failed(ErrorCode.ORDER_NOT_FOUND);
        }
        if(!order.getStatus().equals(Constant.ORDER_STATUS_UNPAIED))
        {
            Log.e("订单状态异常，不是待支付状态");
            return  failed(ErrorCode.ORDER_STATUS_ERROR);
        }

        GoodsInfo goods = goodsInfoService.select_goods_info_on_usefull(bean.getGoods_id());
        //检查商品的货币类型
        if(!"RMB".equals(goods.getCurrency_code()) && !"RMB".equals(goods.getCurrency_type()))
        {
            Log.e("商品不是RMB类型");
            return  failed(ErrorCode.GOODS_CODE_TYPE_ERROR);
        }
        //检查订单的货币类型
        if("RMB".equals(order.getCurrency_code()))
        {
            Log.e("订单currency_code不是RMB类型");
            return  failed(ErrorCode.ORDER_CODE_ERROR);
        }

        //查询支付方式
        PaymentConfigBean ppb = payMapper.get_product_payment_by_pay_id(bean.getPay_id());
        if(null==ppb || "DISABLED".equals(ppb.getStatus()))
        {
            logger.error("支付方式不可用");
            throw new BusinessException(ErrorCode.PAY_INVALID);
        }

        //-----------------------------第三方支付请求和通知日志----------------------------------
//        create_payment_log();
        //-----------------------------第三方支付请求和通知日志----------------------------------

        //判断是哪种支付方式，调用相关的支付
        if("WECHAT".equals(ppb.getProvider()))
        {
            //微信支付
            obj = new WxPayService().get_third_pay_resp(payService,bean,goods,ppb);
        }
        else  if("ALIPAY".equals(ppb.getProvider()))
        {
            //支付宝支付
            obj = new AlipayPayService().get_third_pay_resp(payService,bean,goods,ppb);
        }
        logger.info("return:"+obj.toJSONString());
        return success(obj);
    }

    public PaymentBean get_payment_by_provider(String provider) {
        //search redis
        String redis_key = "PAYMENT_PROVIDER_"+provider;
        Log.d("search redis,key:"+redis_key);
        PaymentBean paymentBean = (PaymentBean) redisService.get(redis_key);
        if(null==paymentBean)
        {
            Log.d("search db...");
            paymentBean = payMapper.get_payment_by_provider(provider);
            redisService.set(redis_key,paymentBean);
        }
        return paymentBean;
    }

    /**
     * 支付成功或失败后的订单处理
     * @param 
     */
    public ResData order_process(String order_id)
    {
    //处理通知之后的业务处理
        try{
            OrderBean order = orderService.get_order_by_id(order_id);
            //系统日志记录
            sysLogBeanService.add_mess_log(order.getId() == null ? "" : order.getId().toString(),"ORDER", order.getBuyer_user_id() == null ? "" : order.getBuyer_user_id().toString(),
                    Json.toJson(order),null,"INFO","ORDER",order.getApp_id() == null ? "" : order.getApp_id().toString(),"CREATE");
            orderService.process_order_pay_back_success(order);
            return  success(null);
        }catch(Exception e){
            Log.d("处理异常");
            e.printStackTrace();
            return failed(ErrorCode.SYS_FAIL);
        }
    }

    public void add_payment_log(PaymentLogBean bean)
    {
        payMapper.add_payment_log(bean);
    }

    /**
     * 余额充值货币类型判断
     * @param bean
     * @throws Exception
     */
    public void check_pay_balance(OrderBean bean) throws Exception{
        //------------------判断货币类型，调对应支付方式-------------------------------
        FinanceCurrency financeCurrency = financeCurrencyService.get_finance_currency_by_code(bean.getCurrency_code());
        if("RMB".equals(financeCurrency.getBuying_currency_type())){
            //说明是账户余额充值 第三方支付

        }
        //非账户余额充值，先查询该充值货币单位的账户余额是多少，和需要充值的作比较，看是否充足
        FinanceAccount fa = financeAccountService.select_finance_account_by_uiaccaac(financeCurrency.getBuying_currency_type(),bean.getAccount_code(),bean.getBuyer_user_id());
        if(!"NORMAL".equals(fa.getStatus())){
            //账户状态异常
            Log.d("账户状态异常");
            throw new Exception("账户状态异常");
        }
        //余额
        Integer balance = fa.getBalance();//账户余额
        if(balance * financeCurrency.getRate() < bean.getTotal_amount()){
            //表示余额不足
            Log.d("余额不足");
            throw new Exception("余额不足");
        }
        //------------------判断货币类型，调对应支付方式-------------------------------
    }

    public PaymentConfigBean get_paymen_config(OrderBean bean){
        return payMapper.get_product_payment_by_pay_id(bean.getPay_id());
    }

    /**
     * 统一支付服务
     * @param bean
     * @return
     */
    public ResData pay(PayTypeBean bean) {


        int total_amount= 0 ;

        try
        {
            OrderBean order = orderService.get_order_by_id(bean.getOrder_id());
            total_amount = bean.getAmount();//原价

            //系统日志记录
            sysLogBeanService.add_mess_log(bean.getOrder_id() == null ? "" : bean.getOrder_id().toString(),"PAY", order.getBuyer_user_id() == null ? "" : order.getBuyer_user_id().toString(),
                    Json.toJson(order),Json.toJson(order),"INFO","ORDER",order.getApp_id() == null ? "" : order.getApp_id().toString(),"LOGIN");
            
            //先判断是否减库存
            GoodsInfo gInfo = goodsInfoService.check_stock(order.getGoods_id().longValue(),order.getNum(),"PAID");

            HashMap<String,Object> map = new HashMap();
            map.put("target_id",order.getId());
            map.put("target_type","ORDER");
            FinanceTradeDetail ftd = financeTradeDetailService.select_finance_trade_details_by_map(map);

            //创建应收应付流水//创建应收应付记录    key对应款项    jsons.getInteger(key)对应金额
            List<FinanceTradeReceivable> ftrs = financeTradeReceivableService.select_finance_trade_receivable_by_finance_trade_details_id(ftd.getId());
            for(FinanceTradeReceivable ftr : ftrs){
                //判断是否有折扣
                if(!StringUtils.isEmpty(bean.getGoods_discount()) && !"0".equals(bean.getGoods_discount()) && "GOODS".equals(ftr.getFund_type()))
                {
                    //调用折扣检查与消费，如果有，计算价格，创建已收已付
                    GoodsDiscount goodsDiscount = goodsDiscountsService.get_goods_discounts(gInfo);
                    if(!bean.getGoods_discount().equals(goodsDiscount.getId().toString())){
                        return failed("","传入的折扣id与对应商品不匹配",null);
                    }
                    total_amount = goodsDiscountPayService.check_goods_discount(gInfo,total_amount,order,ftr,true);
                }

                //判断是否有券
                if(!StringUtils.isEmpty(bean.getCoupon_list()) && !"null".equals(bean.getCoupon_list())){
                    String[] coupons_ids = couponsService.check_coupons(bean.getCoupon_list(),ftr.getFund_type());
                    for(String coupons_id : coupons_ids){
                        if(total_amount != 0){
                            //调用券检查与消费，如果有，计算价格，创建已收已付
                            total_amount = couponsPayService.coupons_on_use(coupons_id,ftr.getFund_type(),total_amount,ftr.getFinance_trade_details_id(),ftr.getId(),order.getBuyer_user_id(),gInfo,true);
                        }else{
                            //无需用券
                            Log.d(ftr.getFund_type() + "无需用券");
                            break;
                        }
                    }
                }
            }
            if(total_amount != order.getTotal_amount()){
                //算后的金额与订单中所需支付的金额不符
                logger.equals("算后的金额与订单中所需支付的金额不符");
                return failed(ErrorCode.SYS_FAIL);
            }

            //判断支付方式
            if("ACCOUNT".equals(bean.getProvider()))
            {
                //余额支付
                order.setUp_curreny_code(bean.getUp_curreny_code());
                return accountPayService.account_pay(order);
            }
            order.setPay_id(Integer.valueOf(bean.getPay_id()));
            PaymentConfigBean ppb = payService.get_paymen_config(order);
            if(null==ppb || "DISABLED".equals(ppb.getStatus()))
            {
                logger.error("支付方式不可用");
                throw new BusinessException(ErrorCode.PAY_INVALID);
            }
            if("ALIPAY".equals(bean.getProvider()))
            {
                //支付宝支付
                JSONObject obj = new AlipayPayService().get_third_pay_resp(payService,order,gInfo,ppb);
                return success(obj);
            }
            if("WECHAT".equals(bean.getProvider()))
            {
                //微信支付
                JSONObject obj = new WxPayService().get_third_pay_resp(payService,order,gInfo,ppb);
                return success(obj);
            }
            return success(null);
        }catch (Exception e)
        {
            Log.e("支付服务出错。 ");
            e.printStackTrace();
            return failed(ErrorCode.SYS_FAIL);
        }
    }
}
